package com.bidevalution.support.util;

import com.bidevalution.support.exception.BizException;
import com.google.common.collect.Maps;
import com.qtp.core.common.HttpTookit;
import com.qtp.core.communication.HttpUtil;
import com.qtp.core.model.RemoteResponse;
import com.qtp.core.util.GsonUtil;
import com.qtp.core.util.OConvertUtils;

import lombok.extern.log4j.Log4j2;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

/**
 * 文件工具类
 *
 * @author shenh@glodon.com
 * @date 2018-3-28 8:54
 */
@Log4j2
public class FileUtil {

	public static final long ONE_KB = 1024L;
	public static final long ONE_MB = 1048576L;
	public static final long ONE_GB = 1073741824L;
	private static Logger log = Logger.getLogger(FileUtil.class);
	/**
	 * 获取文件大小
	 *
	 * @param size 字节
	 * @return
	 */
	public static String getFileSize(long size) {
		java.text.DecimalFormat df = new java.text.DecimalFormat("#.00");
		String fileSizeString = "";
		if (size <= 0) {
			fileSizeString = "0KB";
		} else if (size < ONE_KB) {
			fileSizeString = "1KB";
		} else if (size < ONE_MB) {
			fileSizeString = df.format((double) size / ONE_KB) + "KB";
		} else if (size < ONE_GB) {
			fileSizeString = df.format((double) size / ONE_MB) + "MB";
		} else {
			fileSizeString = df.format((double) size / ONE_GB) + "GB";
		}
		return fileSizeString;
	}

	/**
	 * 检查的目录存在，如果不存在创建它
	 * @param dir
	 */
	public static void checkDirAndCreate(File dir) {
		if (!dir.exists()){
			dir.mkdirs();
		}
	}

	/**
	 * word文件转换pdf功能
	 *
	 * @param md5           文件的MD5值
	 * @param docConvertUrl 转换服务器地址
	 * @return pdfMD5 ：转换后的pdf文件的MD5值
	 * @throws Exception
	 */
	public static String wordToPdf(String md5, String docConvertUrl) throws Exception {

		try {
			log.debug("-------------------开始转换pdf-------------------md5:"+md5);
			// 判断路径是否为空，并且是否以“/”结尾,拼接MD5
			docConvertUrl = checkUrlIsEndWith(docConvertUrl, "topdf.do", md5);
			// 调用 docConvert 组件
			return callDocconvertModule(docConvertUrl);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			throw e;
		}
	}

	/**
	 * pdf转换成图片
	 *
	 * @param md5           pdf文件的MD5值
	 * @param docConvertUrl 转换服务器地址
	 * @return
	 * @throws Exception
	 */
	public static String pdfToImage(String md5, String docConvertUrl) throws Exception {
		try {
			log.debug("-------------------开始转换图片-------------------md5:"+md5);
			// 判断路径是否为空，并且是否以“/”结尾,拼接MD5
			docConvertUrl = checkUrlIsEndWith(docConvertUrl, "toimg.do", md5);
			// 调用 docConvert 组件
			return callDocconvertModule(docConvertUrl);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			throw e;
		}
	}

	/**
	 * 拼接含义MD5码的地址
	 *
	 * @param docConvertUrl 文件服务转换器
	 * @param operateType   文件操作类型
	 * @param md5           文件MD5
	 * @return
	 * @throws Exception
	 */
	private static String checkUrlIsEndWith(String docConvertUrl, String operateType, String md5) throws Exception {
		if (StringUtils.isEmpty(docConvertUrl)) {
			throw new Exception("文件转换服务器地址为空!");
		}
		log.debug("&&&&文件服务器地址为："+docConvertUrl+"&&&&");

		if (!docConvertUrl.endsWith("/")) {
			docConvertUrl += "/";
		}
		log.debug("&&&&需要转换的文件的MD5值为："+md5+"&&&&");
		docConvertUrl += operateType + "?md5=" + md5;
		return docConvertUrl;
	}


	/**
	 * 调用 docConvert 组件
	 *
	 * @param docConvertUrl docConvert地址 包含文件的md5码拼接的路径
	 * @return
	 * @throws Exception
	 */
	private static String callDocconvertModule(String docConvertUrl) throws Exception {
		try {
			RemoteResponse resp = HttpUtil.doPostOrGet("", docConvertUrl, null);
			if (resp != null) {
				String content = resp.getContent();
				Map<String, Object> resultMap = GsonUtil.jsonToMapWithGson(content);
				return getResultM5(resultMap);
			} else {
				log.error("连接docconvert组件出错！");
				throw new Exception("连接docconvert组件出错！");
			}
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			throw e;
		}
	}


	/**
	 * 返回文件的MD5值
	 *
	 * @param resultMap 从docconvert组件获得打数据Map
	 * @return
	 * @throws Exception
	 */
	private static String getResultM5(Map<String, Object> resultMap) throws Exception {
		if (resultMap == null || resultMap.size() == 0) {
			throw new Exception("未获取到docconvert组件返回的信息！");
		}

		if ((Boolean) resultMap.get("success")) {
			String result = OConvertUtils.getString(resultMap.get("result"));
			if (StringUtils.isNotEmpty(result)) {
				return result;
			} else {
				log.error("从docconvert组件获取到的pdf或者图片的MD5值为空");
				throw new Exception("从docconvert组件获取到的pdf或者图片的MD5值为空");
			}
		} else {
			log.error(OConvertUtils.getString(resultMap.get("error")));
			throw new Exception(OConvertUtils.getString(resultMap.get("error")));
		}
	}


	/**
	 * 下载并上传
	 * @param downloadUrl
	 * @param filePath
	 * @param fileId
	 * @param uploadUrl
	 * @return
	 * @throws Exception
	 */
	public static void downloadAndUpload(String downloadUrl,String filePath,String fileId,String uploadUrl) throws Exception{
		try {

			downloadFile(downloadUrl,fileId,filePath);
			log.debug("-------------------开始上传-------------------md5:" + fileId);

			Map<String,Object> param = new HashMap();
			param.put("businessId",fileId);

			//建立连接
			File file = new File(filePath);
			HttpTookit.sendPostFile(uploadUrl,file,filePath,param);
		}catch (Exception e){
			log.error(e.getMessage(), e);
			throw e;
		}finally {
			//删除临时文件
			if(new File(filePath).exists()){
				System.gc();
				new File(filePath).delete();
			}
		}
	}




	/**
	 * 设置查询参数
	 * @param params 参数数组
	 * @return
	 */
	private static NameValuePair[] findQueryString(Map<String, Object> params) {
		// 设置Http Post数据
		if (params != null) {
			int i = 0;
			NameValuePair[] paramArray = new NameValuePair[params.size()];
			for (Map.Entry<String, Object> entry : params.entrySet()) {
				NameValuePair para = new NameValuePair();
				para.setName(entry.getKey());
				para.setValue(entry.getValue()==null?"":entry.getValue().toString());
				paramArray[i++] = para;
			}
			return paramArray;
		}
		else {
			return null;
		}
	}


	public static void main(String[] args) throws Exception {
//        download("http://218.244.141.107:2084/qtp-file-server/UploadedFile/b9a65343-420c-4a12-8df6-31ef7dc9b02f","e99331c9-a949-4a02-8c58-d1cf0c442338fileList-upload-configuration_file_type","");
//        //System.out.println(wordToPdf("276b5a14-beba-440a-b6fa", "http://218.244.141.107:2085/docconvert/")
		//http://218.244.141.107:2085/qtp-file-server/UploadedFile/f93c2925-2f9a-47da-9bd1-f9b869a3d60b
		//downloadAndUpload("http://122.224.244.74:6152/qtp-file-server/UploadedFile/","E:\\工作\\文档\\工程建设2.0\\新工程建设设计文档\\专家抽取增加省库市库的方案2018-5-24.docx","6fca5dc6-ea99-44d5-a8a5-f7d3d62eb43d","http://122.224.244.74:6152/qtp-file-server/fileUploadController/uploadWholeFile.do");
		uploadFile("3FB828049163FC4D093AC83E5BFF4FAC","D:\\newframe\\ggzy2.0\\bid-evalution-new\\trunk\\bid-evalution\\tempFile.pdf","http://122.224.244.74:6152/qtp-file-server/");
	}


	public static void downloadFile(String downloadUrl,String fileId,String filePath) throws Exception{
		InputStream in = null;
		FileOutputStream out = null;
		PostMethod method = null;
		HttpClient client = new HttpClient();
		try {
			log.debug("-------------------开始下载-------------------md5:" + fileId);
			//创建目录
			if(StringUtils.isEmpty(fileId)){
				throw new Exception("获取文件id失败");
			}
			downloadUrl = downloadUrl + fileId;
			File file = new File(filePath);
			file.mkdirs();
			//如果文件存在则删除
			if (file.exists()) {
				file.delete();
			}
			//建立连接
			method = new PostMethod(downloadUrl);
			//执行url请求
			int result = client.executeMethod(method);
			if(result != 200){
				throw new Exception("文件下载失败");
			}
			//获取文件
			in = method.getResponseBodyAsStream();

			//输出保存文件
			out = new FileOutputStream(file);
			byte[] b = new byte[(int)ONE_KB];
			int len = 0;
			while((len=in.read(b))!= -1){
				out.write(b,0,len);
			}
			if (!file.exists()) {
				throw new Exception("upload.文件不存在：" + filePath);
			}
		}finally{
			if(method != null){
				method.releaseConnection();
			}
			if(in != null){
				in.close();
			}
			if(out != null){
				out.close();
			}
		}
	}

	/**
	 * 上传已转换文件 到文件服务器
	 *
	 * @param filePath 已转换文件的路径
	 * @return
	 * @throws Exception
	 */
	public  static void uploadFile(String fileId,String filePath, String fileServerUrl) throws Exception {
		try {
			String uploadUrl = fileServerUrl + "/fileUploadController/uploadWholeFile.do";
			Map<String,Object> param = Maps.newHashMap();
			param.put("businessId",fileId);
			//建立连接
			File file = new File(filePath);
			String result = HttpTookit.sendPostFile(uploadUrl,file,filePath,param);
			//added by daizhifeng ,由于出现pdf没有的情况
			if(!fileId.equals(result)) {
				throw new BizException("文件上传失败,请重新操作");
			}
		}catch (Exception e){
			log.error(e.getMessage(), e);
			throw e;
		} finally {
			//删除临时文件
			if(new File(filePath).exists()){
				System.gc();
				new File(filePath).delete();
			}
		}
	}

	/**
	 * 删除文件
	 *
	 * @param fileName
	 * @throws Exception
	 */
	private void delFile(String fileName) throws Exception {
		//删除文件
		File file1 = new File(fileName);
		if (file1.exists()) file1.delete();
		//删除目录（如果是空目录的话）
		File file2 = new File(file1.getParent());
		if (file2.exists() && file2.isDirectory() && file2.listFiles().length == 0) file2.delete();
	}





}
